package com.bobbygu.bobbyapp.function.replugin

import android.app.ProgressDialog
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.databinding.ViewDataBinding
import android.os.Handler
import android.os.Looper
import android.support.v7.widget.RecyclerView
import android.widget.Button
import android.widget.Toast
import com.bobbygu.lib.mvvm.adapter.*
import com.bobbygu.lib.mvvm.common.BaseActivity
import com.bobbygu.libnet.common.ApiConstants
import com.bobbygu.libnet.common.HostType
import com.bobbygu.libnet.utils.ACache
import com.bobbygu.bobbyapp.BR
import com.bobbygu.bobbyapp.R
import com.bobbygu.bobbyapp.bean.PluginBean
import com.qihoo360.replugin.RePlugin
import com.qihoo360.replugin.model.PluginInfo
import com.qihoo360.replugin.utils.FileUtils
import kotlinx.android.synthetic.main.activity_replugin.*
import java.io.File
import java.io.FileOutputStream
import java.io.InputStream

/**
 * Replugin插件化
 * # time: 2017/11/29 13:38
 * # e-mail: gubojun@csii.com.cn
 * @author 顾博君
 * @since 1.0
 */
class RepluginActivity : BaseActivity<RepluginViewModel, RepluginModel>(), RepluginContract.View {
    override fun getLayoutId(): Int = R.layout.activity_replugin
    override fun getBR(): Int = BR.vm
    var button: Button? = null

    /**
     * 使用自定义ViewHolder添加button点击  也可以直接使用<code>bindExtra(BR.viewmodel, viewModel)</code>
     * 绑定viewmodel在方法中写点击事件
     * 其他使用方法见：[com.bobbygu.bobbyapp.function.main.discover.DiscoverFragment]
     */
    inner class BindingViewHolder(binding: ViewDataBinding) : RecyclerView.ViewHolder(binding.root) {
        init {
            val button = binding.root.findViewById<Button>(R.id.button)
            button.setOnClickListener {
                val pluginBean = viewModel.getPluginList()[adapterPosition]
                val url = "${ApiConstants.getHost(HostType.PRODUCT_HOST)}${pluginBean.fileUrl}/${pluginBean.name}"
//                Toast.makeText(this@RepluginActivity, url, Toast.LENGTH_SHORT).show()
                this@RepluginActivity.button = button
                val localeUrl = ACache.get(context).getAsString(pluginBean.name)
                if (localeUrl != null) {
                    val pluginFile = File(localeUrl)

                    var info: PluginInfo? = null
                    if (pluginFile.exists()) {
                        info = RePlugin.install(localeUrl)
                    }

//                    if (info != null) {
                    RePlugin.startActivity(this@RepluginActivity, RePlugin.createIntent(
                            "demo3",
                            "com.qihoo360.replugin.sample.demo3.MainActivity"))
//                    } else {
//                        Toast.makeText(this@RepluginActivity, "install external plugin failed", Toast.LENGTH_SHORT).show()
//                    }
                } else
                    viewModel.downloadPlugin(url)
            }
        }
    }

    override fun returnDownloadProgress(progress: Int) {
        button?.text = "$progress %"
    }

    override fun initView() {
        BindingRecyclerViewAdapters.setAdapter(
                rv_container,
                ItemBinding.of<PluginBean>(BR.plugin, R.layout.item_plugin)
                        .bindExtra(BR.viewmodel, viewModel),
                viewModel.getPluginList(), null, null,
                BindingRecyclerViewAdapter.ViewHolderFactory { binding -> BindingViewHolder(binding) }
        )

        rv_container.setHasFixedSize(true)//非瀑流RecyclerView减少资源浪费
        BindingRecyclerViewAdapters.setLayoutManager(rv_container, LayoutManagers.linear())

        btn_start_demo1.setOnClickListener {
            RePlugin.startActivity(this@RepluginActivity, RePlugin.createIntent(
                    "com.qihoo360.replugin.sample.demo1",
                    "com.qihoo360.replugin.sample.demo1.MainActivity"))
        }

        btn_start_plugin_for_result.setOnClickListener {
            val intent = Intent()
            intent.component = ComponentName(
                    "demo1",
                    "com.qihoo360.replugin.sample.demo1.activity.for_result.ForResultActivity")
            RePlugin.startActivityForResult(this@RepluginActivity, intent, REQUEST_CODE_DEMO1, null)
        }

//        btn_load_fragment_from_demo1.setOnClickListener{
//            startActivity(Intent(this@RepluginActivity, PluginFragmentActivity::class.java))
//        }

        btn_start_demo3.setOnClickListener {
            // 若没有安装，则直接提示“错误”
            // TODO 将来把回调串联上
            if (RePlugin.isPluginInstalled("demo3")) {
                RePlugin.startActivity(this@RepluginActivity, RePlugin.createIntent(
                        "demo3",
                        "com.qihoo360.replugin.sample.demo3.MainActivity"))
            } else {
                Toast.makeText(this@RepluginActivity, "You must install demo3 first!", Toast.LENGTH_SHORT).show()
            }
        }

        btn_install_apk_from_assets.setOnClickListener {
            val pd = ProgressDialog.show(this@RepluginActivity, "Installing...", "Please wait...", true, true)
            // FIXME: 仅用于安装流程演示 2017/7/24
            Handler(Looper.getMainLooper()).postDelayed({
                simulateInstallExternalPlugin()
                pd.dismiss()
            }, 1000)
        }
    }

    /**
     * 模拟安装或升级（覆盖安装）外置插件
     * 注意：为方便演示，外置插件临时放置到Host的assets/external目录下，具体说明见README
     */
    private fun simulateInstallExternalPlugin() {
        val demo3Apk = "demo3.apk"
        val demo3apkPath = "external" + File.separator + demo3Apk

        // 文件是否已经存在？直接删除重来
        val pluginFilePath = filesDir.absolutePath + File.separator + demo3Apk
        val pluginFile = File(pluginFilePath)
        if (pluginFile.exists()) {
            FileUtils.deleteQuietly(pluginFile)
        }

        // 开始复制
        copyAssetsFileToAppFiles(demo3apkPath, demo3Apk)
        var info: PluginInfo? = null
        if (pluginFile.exists()) {
            info = RePlugin.install(pluginFilePath)
        }

        if (info != null) {
            RePlugin.startActivity(this@RepluginActivity, RePlugin.createIntent(
                    info.name,
                    "com.qihoo360.replugin.sample.demo3.MainActivity"))
        } else {
            Toast.makeText(this@RepluginActivity, "install external plugin failed", Toast.LENGTH_SHORT).show()
        }
    }

    /**
     * 从assets目录中复制某文件内容
     * @param  assetFileName assets目录下的Apk源文件路径
     * @param  newFileName 复制到/data/data/package_name/files/目录下文件名
     */
    private fun copyAssetsFileToAppFiles(assetFileName: String, newFileName: String) {
        var `is`: InputStream? = null
        var fos: FileOutputStream? = null
        val buffsize = 1024

        try {
            `is` = this.assets.open(assetFileName)
            fos = this.openFileOutput(newFileName, Context.MODE_PRIVATE)
            var byteCount = 0
            val buffer = ByteArray(buffsize)
            byteCount = `is`!!.read(buffer)
            while (byteCount != -1) {
                fos!!.write(buffer, 0, byteCount)
                byteCount = `is`.read(buffer)
            }
            fos!!.flush()
        } catch (e: Exception) {
            e.printStackTrace()
        } finally {
            try {
                `is`!!.close()
                fos!!.close()
            } catch (e: Exception) {
                e.printStackTrace()
            }

        }
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
        if (requestCode == REQUEST_CODE_DEMO1 && resultCode == RESULT_CODE_DEMO1) {
            Toast.makeText(this, data.getStringExtra("data"), Toast.LENGTH_SHORT).show()
        }
    }

    companion object {
        private val REQUEST_CODE_DEMO1 = 0x011
        private val RESULT_CODE_DEMO1 = 0x012

        /**
         * @param activity BaseActivity
         */
        fun startActivity(activity: BaseActivity<*, *>) {
            activity.startActivity(RepluginActivity::class.java)
        }
    }
}